#include "mop.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>

#ifdef __linux__
extern char *strptime(const char* s, const char* fmt, const struct tm* tp);
#endif

mop_input input = {
  0,
	0,
	MOP_NOTHING,
  0,
  0,
};

mop_output output = {
  0,
  -1,
  0,
  0,
  0
};

void mop_finish(int status) {
	if (input.path) {
		if (input.path) {
      free(input.path);
    }
    if (input.trash_path) {
      free(input.trash_path);
    }
	}
  if (output.entries) {
    free (output.entries);
  }
	exit(status);
}

void mop_help_and_quit(int status) {
	printf (
			"\n"
			"mop - a filesystem cleaning program\n"
			"(c) 2009, Julien CLEMENT\n"
			"\n"
			"Syntax: mop [OPTIONS] <path>\n"
			"\n"
			"Where [OPTIONS] is a list of options amongst:\n"
			"\n"
      "== Actions:\n"
			"-x <path>  move the obsolete files to trash <path>\n"
			"-X         delete the obsolete files from the filesystem\n"
      "== Behavior:\n"
      "-a         ignore hidden files\n"
      "-l         ignore symbolic links\n"
      "-q         quiet: no output of the obsolete files on stdout, less information.\n"
      "-d         do *not* remove empty directories\n"
      "-e         stop if a stat error is encountered\n"
      "== Time:\n"
      "-t <date>  specify an obsolete date in the form MM/DD/YYYY-hh:mm:ss\n"
      "-p         display the most recent time stamp of each obsolete files\n"    
			"== Misc:\n"
      "-h         display this help screen\n"
      "\n"

			"If no action is specified (see:Actions), the obsolete files remain\n"
      "untouched.\n"
			"\n"
	       );
	mop_finish(status);
}

void mop_parse_args(int argc, char **argv) {
	int k;
	char *arg;
	char opt;
  struct tm tm_struct;
  struct stat stats;

	for (k = 1; k < argc; k++) {
		arg = argv[k]; // Read the next arg

		if (arg[0] == '-') // Check that it is a switch
		{
			if (arg[1] == '-') // Long options are not allowed
			{
				fprintf(stderr, "Long options are not allowed.");
				mop_help_and_quit(EXIT_FAILURE);
			}
			opt = arg[1];  // Skip the hyphen

			// Finally read the option switch
			switch(opt) {
				case 'x': // move to trash
					{
						input.action = MOP_TRASH;
            k++;
            arg = argv[k];
            if (arg[0] == '-') {
              fprintf(stderr, "Expected a path to a directory");
              mop_help_and_quit(EXIT_FAILURE);
            }
            if (stat(arg, &stats) < 0) {
              fprintf(stderr, "stat error on directory %s: ", arg);
              perror("");
              mop_help_and_quit(EXIT_FAILURE);
            }
            if ( !S_ISDIR(stats.st_mode) ) {
              fprintf(stderr, "specified path: %s is not a directory\n", arg);
              mop_help_and_quit(EXIT_FAILURE);
            }
            input.trash_path = strdup(arg);
					}
					break;

				case 'X': // delete
					{
						input.action = MOP_DELETE;
					}
					break;

        case 'a': // ignore hidden files
          {
            input.flags |= MOP_IGNORE_HIDDEN;
          }
          break;

        case 'l': // ignore symlinks
          {
            input.flags |= MOP_IGNORE_SYMLINKS;
          }
          break;

        case 'q' : // quiet mode
          {
            input.flags |= MOP_QUIET;
          }
          break;

        case 'd': // don't remove dirs
          {
            input.flags |= MOP_NO_DIRS;
          }
          break;

        case 'p': // output most recent time stamp
          {
            input.flags |= MOP_SHOW_TIME;
          }
          break;
  
        case 'e': // stop on stat error
          {
            input.flags |= MOP_FATAL;
          }
          break;

        case 't': // obsolete time
          {
            k++;
            arg = argv[k];
            if (arg[0] == '-') {
              fprintf(stderr, "Expected a date format: MM/DD/YYYY-hh:mm:ss\n");
              mop_help_and_quit(EXIT_FAILURE);
            }
            strptime((const char *)argv[k], "%m/%d/%Y-%T", &tm_struct);
            // Hack from:
            // http://www.opengroup.org/onlinepubs/009695399/functions/strptime.html
            tm_struct.tm_isdst = -1; 
            input.time = mktime(&tm_struct);
          }
          break;

        case 'h': // help
           {
              mop_help_and_quit(EXIT_SUCCESS);
           }

				default: // Unrecognized option
					{
						fprintf (stderr, "Unrecognized option switch: '%c'\n", opt);
						mop_help_and_quit(EXIT_FAILURE);
					}
					break;
			}
		}
		else { // It's not a switch: it is the path
			input.path = strdup(arg);
		}
	}

	if (!input.path) { // Path is missing
		fprintf (stderr, "No path was specified.\n");
		mop_help_and_quit(EXIT_FAILURE);
	}
#ifdef DEBUG
	printf ("Mop path:   %s\n", input.path);
	printf ("Mop action: %d\n", input.action);
#endif
}

